<?php

/**
 * @name TradeController
 * @desc 控制器
 */
class TradeController extends UserCommonController
{

    //订单过期时长
    public $count_down_total = 60*15;

    //交易大厅
    public function indexAction(){
        $params = $this->post();
        if(!isset($params['b_type']) || !$params['b_type']){
            $this->ajaxReturn(400, '必须指定币种');
        }

        //k线数据
        $marketModel = MarketPriceModel::getSingleton();

        $sql = "select * from h_market_price where id in(select max(id) from h_market_price where b_type=".$params['b_type']." group by zero_time) order by zero_time desc limit 7";
        $chartList = $marketModel->db->query($sql);
        array_reverse($chartList);
        $min = 0;
        $max = 0;
        foreach($chartList as $val){
            if($min > $val['price']){
                $min = $val['price'];
            }
            if($max < $val['price']){
                $max = $val['price'];
            }
        }

        $zero_time = strtotime(date('Y-m-d'));

        //今日市场价格
        $todayPrice = $marketModel->getNewPrice($params['b_type']);
        //昨日市场价格

        $yesterday = $zero_time - 86400;
        $yesterdayPrice = $marketModel->getLastPrice($params['b_type'], $yesterday);

        //震幅
        $differ = $todayPrice-$yesterdayPrice;
        $up = round(abs($differ)/$yesterdayPrice * 100, 2) . '%';
        $prefix = $differ>=0? '+': '-';
        $upSacle = $prefix.$up;
        //市值（总资产）
        $allConfig = SysConfigModel::getAllConfig();
        $b_index = $params['b_type']==1? 'coin_issue_total': 'sapling_issue_total';
        $issueTotal = $allConfig[$b_index];
        //成交(今日)

        $oderModel = OrderModel::getSingleton();
        $turnover = $oderModel->find(['status'=> 5, 'b_type'=> $params['b_type'], 's_five_time#>='=> $zero_time], 'sum(num) as total');
        $turnoverTotal = $turnover['total']? $turnover['total']: 0;
        //最新成交订单
        $turnoverList = $oderModel->findAll(['status'=> 5, 'b_type'=> $params['b_type'], 's_five_time#>='=> $zero_time], 's_five_time as over_time,trade_type,num,total_price', 's_five_time desc', 0, 10);

        $returnData = [
            'chartList' => $chartList,
            'todayPrice'    => $todayPrice,
            'yesterdayPrice'    => $yesterdayPrice,
            'upSacle'   => $upSacle,
            'issueTotal'    => $issueTotal,
            'turnoverTotal' => $turnoverTotal,
            'turnoverList'  => $turnoverList,
            'chartMaxPrice' => round($max),
            'chartMinPrice' => intval($min)
        ];
        $this->ajaxReturn(0, 'success', $returnData);
    }

    //订单列表
    public function listAction(){
        $params = $this->post();
        if(!isset($params['b_type']) || !$params['b_type']){
            $this->ajaxReturn(400, '必须指定币种');
        }
        if(!isset($params['l_type']) || !$params['l_type']){
            $this->ajaxReturn(400, '必须列表类型');
        }

        $row = $params['pageSize'] ?? 12;
        $page = $params['page'] ?? 1;

        $where = "o.is_delete = 0 AND o.b_type = ? AND ";
        $bindValues = [$params['b_type']];
        $cond = [
            'o.is_delete' => 0,
            'o.b_type'    => $params['b_type'],
            'o.status'    => 1
        ];

        //1买入 2卖出 3撤单 4交易中 5成交
        if($params['l_type'] == 1){

            $where .= "o.trade_type = 2 AND (o.status = 1 OR (o.status = 2 AND o.s_two_time < ?)) AND ";
            $bindValues[] = time()-$this->count_down_total;

//            $cond['o.trade_type'] = 2;    //买入列表展示出售需求订单
        }
        if($params['l_type'] == 2){

            $where .= "o.trade_type = 1 AND (o.status = 1 OR (o.status = 3 AND o.s_three_time < ?)) AND ";
            $bindValues[] = time()-$this->count_down_total;


//            $cond['o.trade_type'] = 1;    //卖出列表展示买入需求订单
        }
        if($params['l_type'] == 3){     //当前用户的发布列表
//            $cond['o.issue_user_id'] = $this->user_info['user_id'];

            $where .= "o.issue_user_id = ? AND (o.status = 1 OR (o.status = ? AND o.s_two_time < ?) OR (o.status = ? AND o.s_three_time < ?)) AND ";
            $bindValues[] = $this->user_info['user_id'];
            $bindValues[] = 2;
            $bindValues[] = time()-$this->count_down_total;
            $bindValues[] = 3;
            $bindValues[] = time()-$this->count_down_total;
        }
        if($params['l_type'] == 4){     //交易中的订单
//            $cond['o.status#in'] = [2, 3, 4];
//            $cond['o.buyer_user_id|seller_user_id'] = $this->user_info['user_id'];

            $where .= "o.status IN(2,3,4) AND ";

        }
        if($params['l_type'] == 5){ //当前用户的完成交易列表
//            $cond['o.status'] = 5;
//            $cond['o.buyer_user_id|seller_user_id'] = $this->user_info['user_id'];

            $where .= "o.status = 5 AND (o.buyer_user_id = ? OR o.seller_user_id = ?)";
            $bindValues[] = $this->user_info['user_id'];
            $bindValues[] = $this->user_info['user_id'];
        }

        $where = rtrim($where, " AND ");
        $orderModel = OrderModel::getSingleton();
        $list = $orderModel->db
            ->field('o.*,u.nick_name')
            ->alias('o')
            ->join(['user', 'u'], ['o.issue_user_id'=> 'u.user_id'], 'left join')
            ->where($where, $bindValues)
//                ->where_c($cond)
            ->order('o.order_id desc')
            ->limit(($page - 1) * $row, $row)
            ->select();
        $total = $orderModel->db
            ->alias('o')
            ->join(['user', 'u'], ['o.issue_user_id'=> 'u.user_id'], 'left join')
            ->where($where, $bindValues)
//            ->where_c($cond)
            ->count();

        $nlist = [];
        foreach($list as $val){
            $payTypeArr = explode(',', $val['pay_type']);
            $payTextArr = [];
            foreach($payTypeArr as $vv){
                $payTextArr[] = OrderModel::$payTypeFrist[$vv];
            }
            //判断用户买/卖身份
            $show = '';
            if($this->user_info['user_id'] == $val['buyer_user_id']){
                $show = '买';
            }
            if($this->user_info['user_id'] == $val['seller_user_id']){
                $show = '卖';
            }
            $temp = [
                'order_no'  => $val['order_no'],
                'nick_name' => $val['nick_name']?$val['nick_name']: '',
                'num'   => $val['num'],
                'unit_price'    => $val['unit_price'],
                'pay_type'  => $val['pay_type'],
                'create_time'   => $val['create_time'],
                'handle'    => $val['issue_user_id'] == $this->user_info['user_id']? 0: 1,
                'status'    => $val['status'],
                'total_price'   => $val['total_price'],
                'show'  => $show

            ];
            $nlist[] = $temp;

            //刷新订单状态
            if($val['status'] == 2 && $val['s_two_time']<(time()-$this->count_down_total)){
                $orderModel->update(['order_no'=>$val['order_no']], ['status'=> 1, 'buyer_user_id'=> 0, 's_two_time'=> 0]);
                $val['status'] = 9;  //超时自动取消
                $val['remark'] = OrderLogModel::$remarkArr[9]. '系统超时，自动取消';
                $val['author'] = 'x_';
                $this->addOrderLog($val);
            }
            if($val['status'] == 3 && $val['s_three_time']<(time()-$this->count_down_total)){
                $orderModel->update(['order_no'=>$val['order_no']], ['status'=> 1, 'seller_user_id'=> 0, 's_two_time'=> 0]);
                $val['status'] = 9;  //超时自动取消
                $val['remark'] = OrderLogModel::$remarkArr[9]. '系统超时，自动取消';
                $val['author'] = 'x_';
                $this->addOrderLog($val);
            }
        }

        $data = [
            'list' => $nlist,
            'total' => intval($total),
            'current'   => intval($page),
            'pageSize'  => intval($row),
            'page'  => intval($page),
            'pageNum'   => ceil($total/$row)
        ];

        $this->ajaxReturn(0, '', $data);
    }

    //详情
    public function detailAction(){
        $params = $this->post();

        if(!isset($params['order_no']) || !$params['order_no']){
            $this->ajaxReturn(400, '必须指定订单号');
        }

        $orderModel = OrderModel::getSingleton();
        $detail = $orderModel->db
            ->field('o.*,buyer.nick_name as buyer_name,seller.nick_name as seller_name')
            ->alias('o')
            ->join(['user', 'buyer'], ['o.buyer_user_id'=> 'buyer.user_id'], 'left join')
            ->join(['user', 'seller'], ['o.seller_user_id'=> 'seller.user_id'], 'left join')
            ->where_c(['o.order_no'=> $params['order_no']])
            ->select();
        $detail = $detail[0];

        if(!$detail || $detail['status'] == 8){
            $this->ajaxReturn(400, '挂单已撤销或不存在');
        }
        if($detail['status'] == 1){
            $this->ajaxReturn(400, '订单已过期或未下单');
        }
        if($detail['status'] == 2 && $detail['s_two_time']<(time()-$this->count_down_total)){
            //更新订单状态(重新回发布状态)
            $orderModel->update(['order_no'=>$detail['order_no']], ['status'=> 1, 'buyer_user_id'=> 0, 's_two_time'=> 0]);
            $detail['status'] = 9;  //超时自动取消
            $detail['remark'] = OrderLogModel::$remarkArr[9]. '系统超时，自动取消';
            $detail['author'] = 'x_';
            $this->addOrderLog($detail);
            $this->ajaxReturn(400, '订单已过期,须重新下单', $detail);
        }
        if($detail['status'] == 3 && $detail['s_three_time']<(time()-$this->count_down_total)){
            //更新订单状态(重新回发布状态)
            $orderModel->update(['order_no'=>$detail['order_no']], ['status'=> 1, 'seller_user_id'=> 0, 's_three_time'=> 0]);
            $detail['status'] = 9;  //超时自动取消
            $detail['remark'] = OrderLogModel::$remarkArr[9]. '系统超时，自动取消';
            $detail['author'] = 'x_';
            $this->addOrderLog($detail);
            $this->ajaxReturn(400, '订单已过期,须重新下单', $detail);
        }

        //计算倒计时
        $count_down_time = 0;
        if($detail['status'] == 2){
            $count_down_time = $this->count_down_total-(time()-$detail['s_two_time']);
        }
        if($detail['status'] == 3){
            $count_down_time = $this->count_down_total-(time()-$detail['s_three_time']);
        }

        //实时计算佣金
        $allConfig = SysConfigModel::getAllConfig();
        $b_type = $detail['b_type']==1? 'coin_trade_sacle': 'sapling_trade_sacle';
        $commission_sacle = $allConfig[$b_type];
        $commission = $detail['num'] * $commission_sacle;

        //获取默认银行卡
        $defaultBank = 0;
        $payTypeArr = explode(',', $detail['pay_type']);
        if(in_array(3, $payTypeArr)){
            $userBankModel = UserbankModel::getSingleton();
            $defaultBank = $userBankModel->find(['user_id'=> $this->user_info['user_id'], 'is_default'=> 1],'bank_name,account_name,bank_no,bank_address,bank_branch_name');
        }

        $issueInfo = UserModel::getSingleton()->find(['user_id'=> $detail['issue_user_id']]);
        //联系方式
        $contact_group = [
            'wechat'    => '',
            'alipay'    => '',
            'moble'    => '',
        ];
        $contactArr = explode(',', $detail['contact']);
        if($contactArr){
            //微信
            if(in_array(1, $contactArr)){
                $contact_group['wechat'] = $issueInfo['wechat'];
            }
            //支付宝
            if(in_array(2, $contactArr)){
                $contact_group['alipay'] = $issueInfo['alipay'];
            }
            //手机号
            if(in_array(3, $contactArr)){
                $contact_group['moble'] = $issueInfo['moble'];
            }
        }

        //支付方式
        $pay_group = [
            'wechat'    => '',
            'alipay'    => '',
            'default_bank'    => '',
        ];
        $payArr = explode(',', $detail['pay_type']);

        if($payArr){
            //微信
            if(in_array(1, $payArr)){
                $pay_group['wechat'] = $issueInfo['wechat'];
            }
            //支付宝
            if(in_array(2, $payArr)){
                $pay_group['alipay'] = $issueInfo['alipay'];
            }
            //银行卡
            if(in_array(3, $payArr)){
                $pay_group['default_bank'] = $defaultBank;
            }
        }

        $returnData = [
            'order_no'  => $detail['order_no'],
            'buyer_name'    => $detail['buyer_name']? $detail['buyer_name']: '',
            'seller_name'   => $detail['seller_name']? $detail['seller_name']: '',
            'num'   => $detail['num'],
            'unit_price'    => $detail['unit_price'],
            'total_price'   => $detail['total_price'],
            'pay_type'  => $detail['pay_type'],
            'contact'  => $detail['contact'],
            'contact_group'  => $contact_group,
            'random'    => substr($detail['order_no'], -6),
            'count_down_time'  => $count_down_time,
            'commission'    => $commission,
            'status'    => $detail['status'],
            'pay_group' => $pay_group,
            'b_type'    => $detail['b_type']
        ];

        if($this->user_info['user_id'] == $detail['buyer_user_id']){
            $returnData['show'] = 'buy';
        }
        if($this->user_info['user_id'] == $detail['seller_user_id']){
            $returnData['show'] = 'sell';
        }

        $this->ajaxReturn(0, 'success', $returnData);
    }

    //获取构树链实时价格
    public function coinpriceAction(){
        $marketModel = MarketPriceModel::getSingleton();
        $coinNewPrice = $marketModel->getNewPrice(1);

        $this->ajaxReturn(0, 'success', $coinNewPrice);
    }

    //发布交易
    public function addAction(){
        $params = $this->post();

        if(!isset($params['b_type']) || !trim($params['b_type'])){
            $this->ajaxReturn(400, '未获取到币种');
        }
        if(!isset($params['pay_pwd']) || !trim($params['pay_pwd'])){
            $this->ajaxReturn(400, '必须输入支付密码');
        }

        $userModel = UserModel::getSingleton();
        $userInfo = $userModel->find(['user_id'=> $this->user_info['user_id']]);

        //验证支付密码
        if($userInfo['pay_pwd'] != md5($params['pay_pwd'])){
            $this->ajaxReturn(400, '支付密码错误');
        }

        $orderModel = OrderModel::getSingleton();

        $rule = [
            'b_type'    => 'require|in:1,2',
            'trade_type'     => 'require|in:1,2',   //1买 2卖
            'num' => 'require|integer|between:1,1000000',
            'unit_price'=> 'require|number|between:0.0001,1000000',
            'pay_type'  => 'require',       //格式 1,2,3 （1微信，2支付宝，3银行卡）
            'contact'   => 'require',       //联系方式 1手机号，2微信，3支付宝
            'pay_pwd'   => 'require'
        ];
        $msg = [
            'b_type.require'    => '未获取到币种',
            'b_type.in'    => '错误的币种类型',
            'trade_type.require' => '必须选择买卖类型',
            'trade_type.in'   => '不正确的买卖类型',
            'num.require' => '必须输入挂单数量',
            'num.integer'   => '挂单数量必须为整数',
            'num.between'   => '挂单数量必须为整数',
            'unit_price.require'   => '必须输入单价',
            'unit_price.number'   => '单价输入不正确',
            'unit_price.between'   => '单价不正确.',
            'pay_type.require'   => '必须选择支付方式',
            'contact.require'   => '必须选择联系方式',
            'pay_pwd.require'   => '必须输入支付密码',
        ];
        $validate = new \Vendor\Kvalidate($rule,$msg);
        if(!$validate->check($params)){
            $this->ajaxReturn(400, $validate->getError());
        }

        //计算佣金
        $b_type = $params['b_type']==1? 'coin_trade_sacle': 'sapling_trade_sacle';
        $allConfig = SysConfigModel::getAllConfig();
        $commission_sacle = $allConfig[$b_type];
        $commission_num = $params['num'] * $commission_sacle;

        $params['issue_user_id'] = $this->user_info['user_id'];
        //购买
        if($params['trade_type'] == 1){
            $params['buyer_user_id'] = $this->user_info['user_id'];
            $params['seller_user_id'] = 0;
        }
        //出售
        if($params['trade_type'] == 2){
            $params['seller_user_id'] = $this->user_info['user_id'];
            $params['buyer_user_id'] = 0;
        }

        //订单号
        $params['order_no'] = \Vendor\Kstring::orderNo20();
        $params['total_price'] = round($params['unit_price']*$params['num'], 2);
        $params['commission_sacle'] = $commission_sacle;
        $params['commission_num'] = $commission_num;
        $params['status'] = 1;

        //卖出需要的额度判断
        if($params['trade_type'] == 2){
            $checkRes = $this->checkUserFunds($this->user_info['user_id'], $params['b_type'], $params['num'], $commission_num);
            if($checkRes){
                $this->ajaxReturn(400, $checkRes);
            }
        }

        //统计操作
        if(isset($params['tips'])){
            unset($params['issue_user_id']);
            if(isset($params['buyer_user_id'])) unset($params['buyer_user_id']);
            if(isset($params['seller_user_id'])) unset($params['seller_user_id']);
            unset($params['status']);
            unset($params['pay_pwd']);
            $this->ajaxReturn(0, 'success', $params);
        }

        if(!$orderModel->add($params)){
            $this->ajaxReturn(400, '发布失败');
        }

        //记录订单log
        $params['remark'] = OrderLogModel::$remarkArr[1].'发布挂单';
        $orderLogModel = OrderLogModel::getSingleton();
        $params['author'] = 'u_'.$this->user_info['user_id'];
        $orderLogModel->add($params);

        $this->ajaxReturn(0, 'success');
    }

    //账户交易限额和可用余额的判断
    public function checkUserFunds($user_id, $b_type, $trade_num, $trade_commission){
        $userModel = UserModel::getSingleton();
        $userInfo = $userModel->find(['user_id'=> $user_id]);

        //每天挂单总额是否超系统设置限额(卖出需要判断,不算佣金)
        $total = $this->getUserLockFunds($this->user_info['user_id'], $b_type);
        $allConfig = SysConfigModel::getAllConfig();
        $setting_key = $b_type==1? 'sell_coin_top': 'sell_sapling_top';
        if($allConfig[$setting_key]>0 && $allConfig[$setting_key]<($total+$trade_num)){
            return '挂卖总额超限(最高:'.$allConfig[$setting_key].',已挂卖:'.$total.')';
//            $this->ajaxReturn(400, '挂单总额超限(最高:'.$allConfig['sell_coin_top'].',已挂单:'.$total.')');
        }

        //已冻结的可用资金
        $f_funds = $this->sellefundsAction($user_id, $b_type);
        $b_type = $b_type==1? 'coin': 'sapling';
        if(($userInfo[$b_type]-$f_funds) < ($trade_num+$trade_commission)){
            return '数量不足（可用:'.$userInfo[$b_type].',总挂单+佣金:'.$f_funds.',本次交易总额:'.($trade_num+$trade_commission).'）';
//            $this->ajaxReturn(400, '数量不足（可用:'.$userInfo[$b_type].',总挂单+佣金:'.$f_funds.',本次交易总额:'.$trade_total.'）');
        }

        return 0;
    }

    //计算账户冻结资金（已挂单的资金）
    public function sellefundsAction($user_id, $b_type){
        $orderModel = OrderModel::getSingleton();
//        $total = $orderModel->find([
//            'seller_user_id'=> $user_id,
//            'b_type'=> $b_type,
//            'status#in'=> [1,2,3,4]], 'sum(num) as total, sum(commission_num) as commission_total');

        $thatTime = time()-$this->count_down_total;
        $zeroTime = strtotime(date('Y-m-d'));
        $orderModel = OrderModel::getSingleton();
        //已发布未购买和已支付的的所有订单
        $userTotal1 = $orderModel->find([
            'seller_user_id'=> $user_id,
            'status#in'    => [1, 2, 4],
            'b_type'    => $b_type,
            'is_delete'     => 0,
        ], 'sum(num) as total, sum(commission_num) as commission_total');

        //卖方已下单但未购买（未超过15分钟）的所有订单
        $userTotal3 = $orderModel->find([
            'seller_user_id'=> $user_id,
            'status'    => 3,
            'b_type'    => $b_type,
            'is_delete'     => 0,
            's_three_time#>'=> $thatTime
        ], 'sum(num) as total, sum(commission_num) as commission_total');

        $total = $userTotal1['total']+$userTotal1['commission_total'] + $userTotal3['total']+$userTotal3['commission_total'];
        return $total;
    }

    //计算账户单日交易额和正在处理的挂单、订单
    public function getUserLockFunds($user_id, $b_type){
        $thatTime = time()-$this->count_down_total;
        $zeroTime = strtotime(date('Y-m-d'));
        $orderModel = OrderModel::getSingleton();
        //已发布未购买和已支付的的所有订单
        $userTotal1 = $orderModel->find([
            'seller_user_id'=> $user_id,
            'status#in'    => [1, 2, 4],
            'b_type'    => $b_type,
            'is_delete'     => 0,
        ], 'sum(num) as total');
        //卖方已下单但未购买（未超过15分钟）的所有订单
        $userTotal3 = $orderModel->find([
            'seller_user_id'=> $user_id,
            'status'    => 3,
            'b_type'    => $b_type,
            'is_delete'     => 0,
            's_three_time#>'=> $thatTime
        ], 'sum(num) as total');
        //今日已成交的订单
        $userTotal4 = $orderModel->find([
            'seller_user_id'=> $user_id,
            'status#in'    => 5,
            'b_type'    => $b_type,
            'is_delete'     => 0,
            's_five_time#>'=> $zeroTime
        ], 'sum(num) as total');
        $total = $userTotal1['total'] + $userTotal3['total'] + $userTotal4['total'];
//        $total = $userTotal1['total'] + $userTotal4['total'];
        return $total;
    }

    //获取支付方式
    public function getpaytypeAction(){
        $userModel = UserModel::getSingleton();
        $userBankModel = UserbankModel::getSingleton();

        $userInfo = $userModel->find(['user_id'=> $this->user_info['user_id']]);
        $bankList = $userBankModel->find(['user_id'=> $this->user_info['user_id'], 'is_delete'=> 0]);

        $wechat = trim($userInfo['wechat'])? 1 : 0;
        $alipay = trim($userInfo['alipay'])? 1 : 0;
        $bank = $bankList? 1 : 0;

        $this->ajaxReturn(0, 'success', [1=> $wechat, 2=> $alipay, 3=> $bank]);
    }

    //计算佣金
    public function commissionAction(){
        $params = $this->post();
        $rule = [
            'b_type'    => 'require|in:1,2',
            'num'     => 'require|number',   //1买 2卖
        ];
        $msg = [
            'b_type.require'    => '未获取到币种',
            'b_type.in' => '错误的币种类型',
            'num.require' => '必须输入数量',
        ];
        $validate = new \Vendor\Kvalidate($rule,$msg);
        if(!$validate->check($params)){
            $this->ajaxReturn(400, $validate->getError());
        }

        $b_type = $params['b_type']==1? 'coin_trade_sacle': 'sapling_trade_sacle';
        $allConfig = SysConfigModel::getAllConfig();
        $commission = $params['num'] * $allConfig[$b_type];

        $this->ajaxReturn(0, 'success', $commission);
    }

    //订单操作
    public function operateAction(){
        $params = $this->post();

        //每日允许交易时间判断
        $allConfig = SysConfigModel::getAllConfig();
        $trade_time_s = strtotime(date('Y-m-d ').$allConfig['trade_time_s']);
        $trade_time_e = strtotime(date('Y-m-d ').$allConfig['trade_time_e']);
        if(time()< $trade_time_s || time()>$trade_time_e){
            $this->ajaxReturn(400, '当前时间不在每日交易时间范围内');
        }

        $rule = [
            'order_no'     => 'require',   //订单ID
            'operate_type'  => 'require|in:2,3,4,5,6,7,8',    //2买方下单 3卖方下单 4买方已支付 5卖方已释放 6卖方取消 7买家取消 8发布方撤销
        ];
        $msg = [
            'order_no.require' => '未获取到订单编号',
            'operate_type.require' => '未获取到操作类型',
            'operate_type.in' => '错误的操作类型',
        ];
        $validate = new \Vendor\Kvalidate($rule,$msg);
        if(!$validate->check($params)){
            $this->ajaxReturn(400, $validate->getError());
        }

        $orderModel = OrderModel::getSingleton();
        $orderDetail = $orderModel->find(['order_no'=> $params['order_no']]);
        if(!$orderDetail){
            $this->ajaxReturn(400, '订单不存在');
        }

        //买方下单
        if($params['operate_type'] == 2){
            if($orderDetail['status'] != 1){
                $this->ajaxReturn(400, '挂单正在交易中，请刷新重试');
            }
            if($orderDetail['trade_type'] != 2){
                $this->ajaxReturn(400, '此挂单非出售需求');
            }
            if($orderDetail['buyer_user_id'] == $orderDetail['issue_user_id']){
                $this->ajaxReturn(400, '此挂单非出售需求');
            }
            if($orderDetail['issue_user_id'] == $this->user_info['user_id']){
                $this->ajaxReturn(400, '不能向自己购买');
            }
            if(!$orderModel->update(['order_no'=> $params['order_no']], ['status'=> 2, 'buyer_user_id'=> $this->user_info['user_id'], 's_two_time'=> time()])){
                $this->ajaxReturn(400, '下单失败');
            }
            $orderDetail['status'] = 2;
            $orderDetail['remark'] = OrderLogModel::$remarkArr[2]. '买家下单';
            $orderDetail['buyer_user_id'] = $this->user_info['user_id'];
            $orderDetail['author'] = 'u_'.$this->user_info['user_id'];
            $this->addOrderLog($orderDetail);
            $this->ajaxReturn(0, 'success');
        }
        //卖方下单
        if($params['operate_type'] == 3){
            if($orderDetail['status'] != 1){
                $this->ajaxReturn(400, '挂单正在交易中，请刷新重试');
            }
            if($orderDetail['trade_type'] != 1){
                $this->ajaxReturn(400, '此挂单非购买需求');
            }
            if($orderDetail['seller_user_id'] == $orderDetail['issue_user_id']){
                $this->ajaxReturn(400, '此挂单非购买需求.');
            }
            if($orderDetail['issue_user_id'] == $this->user_info['user_id']){
                $this->ajaxReturn(400, '不能向自己出售');
            }

            //实时计算佣金
            $b_type = $orderDetail['b_type']==1? 'coin_trade_sacle': 'sapling_trade_sacle';
            $commission_sacle = $allConfig[$b_type];
            $commission_total = $orderDetail['num'] * $commission_sacle;

            //卖出需要的额度判断
            $checkRes = $this->checkUserFunds($this->user_info['user_id'], $orderDetail['b_type'], $orderDetail['num'], $commission_total);
            if($checkRes){
                $this->ajaxReturn(400, $checkRes);
            }

            if(!$orderModel->update(['order_no'=> $params['order_no']], ['status'=> 3, 'seller_user_id'=> $this->user_info['user_id'], 's_three_time'=> time()])){
                $this->ajaxReturn(400, '下单失败.');
            }

            $orderDetail['status'] = 3;
            $orderDetail['remark'] = OrderLogModel::$remarkArr[3]. '卖家下单';
            $orderDetail['seller_user_id'] = $this->user_info['user_id'];
            $orderDetail['author'] = 'u_'.$this->user_info['user_id'];
            $this->addOrderLog($orderDetail);
            $this->ajaxReturn(0, 'success');
        }
        //买方支付
        if($params['operate_type'] == 4){
            if(!in_array($orderDetail['status'], [2, 3])){
                $this->ajaxReturn(400, '订单非待支付状态');
            }
            if($orderDetail['buyer_user_id'] != $this->user_info['user_id']){
                $this->ajaxReturn(400, '非法操作');
            }
            //确认支付密码
            $userModel = UserModel::getSingleton();
            $userInfo = $userModel->find(['user_id'=> $this->user_info['user_id']], 'pay_pwd');
            if(!isset($params['pay_pwd']) || $userInfo['pay_pwd']!=md5($params['pay_pwd'])){
                $this->ajaxReturn(400, '支付密码错误');
            }
            if(!$orderModel->update(['order_no'=> $params['order_no']], ['status'=> 4, 's_four_time'=> time()])){
                $this->ajaxReturn(400, '确认失败.');
            }
            $orderDetail['status'] = 4;
            $orderDetail['remark'] = OrderLogModel::$remarkArr[4]. '买家已支付';
            $orderDetail['author'] = 'u_'.$this->user_info['user_id'];
            $this->addOrderLog($orderDetail);
            $this->ajaxReturn(0, 'success');
        }
        //卖方释放货币
        if($params['operate_type'] == 5){
            if($orderDetail['status'] != 4){
                $this->ajaxReturn(400, '买方未支付，请联系买方“确认支付”');
            }
            if($orderDetail['buyer_user_id'] == $this->user_info['user_id']){
                $this->ajaxReturn(400, '请勿对自己账户释放货币');
            }
            if($orderDetail['seller_user_id'] != $this->user_info['user_id']){
                $this->ajaxReturn(400, '非法操作');
            }
            //确认支付密码
            $userModel = UserModel::getSingleton();
            $userInfo = $userModel->find(['user_id'=> $this->user_info['user_id']], 'pay_pwd');
            if(!isset($params['pay_pwd']) || $userInfo['pay_pwd']!=md5($params['pay_pwd'])){
                $this->ajaxReturn(400, '支付密码错误');
            }
            try{
                \Vendor\DB::startTrans();

                //实时计算佣金
                $b_type = $orderDetail['b_type']==1? 'coin_trade_sacle': 'sapling_trade_sacle';
                $commission_sacle = $allConfig[$b_type];
                $commission = $orderDetail['num'] * $commission_sacle;
                //出售方应扣总额
                $amount = $orderDetail['num'] + $commission;

                $userModel = UserModel::getSingleton();

                //减扣账户
                $downUser = $userModel->find(['user_id'=> $orderDetail['seller_user_id']]);
                //增加账户
                $upUser = $userModel->find(['user_id'=> $orderDetail['buyer_user_id']]);

                $model = '';
                $b_key = '';
                if($orderDetail['b_type'] == 1){
                    $model = CoinLogModel::getSingleton();
                    $b_key = 'coin';
                }else if($orderDetail['b_type'] == 2){
                    $model = SaplingLogModel::getSingleton();
                    $b_key = 'sapling';
                    $downUser['f_'.$b_key] = 0;
                    $upUser['f_'.$b_key] = 0;
                }
                if($model == '') {
                    $this->ajaxReturn(400, '不支持的币种');
                }

                //减扣
                $res = $userModel->setDec(['user_id'=> $downUser['user_id']], $b_key, $amount);
                if(!$res){
                    \Vendor\DB::rollback();
                    $this->ajaxReturn(400, '操作失败');
                }
                //增加
                $res = $userModel->setInc(['user_id'=> $upUser['user_id']], $b_key, $orderDetail['num']);
                if(!$res){
                    \Vendor\DB::rollback();
                    $this->ajaxReturn(400, '操作失败.');
                }

                //减扣出售数量
                $amount_before = $downUser[$b_key];
                $amount = $orderDetail['num'];
                $amount_after = $amount_before - $amount;
                $res = $model->add([
                    'charge_id' => 0,
                    'order_no'  => $orderDetail['order_no'],
                    'type'  => 2,
                    'cate'  => 9,   //9交易卖出
                    'user_id'=> $downUser['user_id'],
                    'from_user_id'  => $downUser['user_id'],
                    'amount_before' => $downUser['coin'],
                    'amount'    => $amount,
                    'amount_after'  => $amount_after,
                    'f_amount_before' => $downUser['f_'.$b_key],
                    'f_amount'    => 0,
                    'f_amount_after'  => $downUser['f_'.$b_key],
                    'description'   => '['.CoinLogModel::$cateArr[9].']' . '减扣'.$orderDetail['num'] .'出售给：'. $upUser['moble'] .'(订单号：'.$orderDetail['order_no'].')'
                ]);
                if(!$res){
                    \Vendor\DB::rollback();
                    $this->ajaxReturn(400, '充值失败');
                }
                //扣除佣金
                $amount_before = $amount_after;
                $amount = $commission;
                $amount_after = $amount_before - $commission;
                $res = $model->add([
                    'charge_id' => 0,
                    'order_no'  => $orderDetail['order_no'],
                    'type'  => 2,
                    'cate'  => 10,   //9交易卖出
                    'user_id'=> $downUser['user_id'],
                    'from_user_id'  => $downUser['user_id'],
                    'amount_before' => $amount_before,
                    'amount'    => $amount,
                    'amount_after'  => $amount_after,
                    'f_amount_before' => $downUser['f_'.$b_key],
                    'f_amount'    => 0,
                    'f_amount_after'  => $downUser['f_'.$b_key],
                    'description'   => '['.CoinLogModel::$cateArr[10].']' . '扣除佣金:'.$amount .'（订单号：'.$orderDetail['order_no'].'出售给:'. $upUser['moble'].',数量:' . $orderDetail['num'].'系统实时比例：'. $commission_sacle .'）'
                ]);
                if(!$res){
                    \Vendor\DB::rollback();
                    $this->ajaxReturn(400, '操作失败.');
                }

                //入账记录
                $res = $model->add([
                    'charge_id' => 0,
                    'type'  => 1,
                    'cate'  => 8,   //3转入
                    'user_id'=> $upUser['user_id'],
                    'from_user_id'  => $downUser['user_id'],
                    'amount_before' => $upUser[$b_key],
                    'amount'    => $orderDetail['num'],
                    'amount_after'  => $upUser[$b_key] + $orderDetail['num'],
                    'f_amount_before' => $upUser['f_'.$b_key],
                    'f_amount'    => 0,
                    'f_amount_after'  => $upUser['f_'.$b_key],
                    'description'   => '['.CoinLogModel::$cateArr[8].']' . '买入增加'.$orderDetail['num'].'出售方：' . $downUser['moble'] . '订单号：'.$orderDetail['order_no']
                ]);
                if(!$res){
                    \Vendor\DB::rollback();
                    $this->ajaxReturn(400, '操作失败.');
                }

                //修改订单状态
                if(!$orderModel->update(['order_no'=> $params['order_no']], ['status'=> 5, 's_five_time'=> time(), 'commission_sacle'=> $commission_sacle, 'commission_num'=> $commission])){
                    $this->ajaxReturn(400, '释放失败.');
                }

                \Vendor\DB::commit();
            }catch(\Yaf\Exception $e){
                \Vendor\DB::rollback();
                $this->ajaxReturn(400, '操作失败');
            }

            $orderDetail['status'] = 5;
            $orderDetail['remark'] = OrderLogModel::$remarkArr[5]. '卖家释放货币';
            $orderDetail['author'] = 'u_'.$this->user_info['user_id'];
            $this->addOrderLog($orderDetail);
            $this->ajaxReturn(0, 'success');
        }
        //买方撤销
        if($params['operate_type'] == 6){
            if($orderDetail['buyer_user_id'] != $this->user_info['user_id']){
                $this->ajaxReturn(400, '非法操作');
            }
            //能操作撤销的状态
            if(!in_array($orderDetail['status'], [1, 2, 3])){
                $this->ajaxReturn(400, '订单不可撤销状态');
            }
            $upData = ['status'=> 1];
            //如果是卖方下的单
            if($orderDetail['status'] == 3){
                $upData['seller_user_id'] = 0;
            }
            if(!$orderModel->update(['order_no'=> $orderDetail['order_no']], $upData)){
                $this->ajaxReturn(400, '操作失败');
            }
            //记录log
            $orderDetail['status'] = 6;
            $orderDetail['remark'] = OrderLogModel::$remarkArr[6]. '买家撤销订单';
            $orderDetail['author'] = 'u_'.$this->user_info['user_id'];
            $this->addOrderLog($orderDetail);
            $this->ajaxReturn(0, 'success');
        }
        //卖方撤销
        if($params['operate_type'] == 7){
            if($orderDetail['seller_user_id'] != $this->user_info['user_id']){
                $this->ajaxReturn(400, '非法操作');
            }
            //能操作撤销的状态
            if(!in_array($orderDetail['status'], [1, 2, 3])){
                $this->ajaxReturn(400, '订单不可撤销状态');
            }
            $upData = ['status'=> 1];
            //如果是卖方下的单
            if($orderDetail['status'] == 3){
                $upData['seller_user_id'] = 0;
            }
            if(!$orderModel->update(['order_no'=> $orderDetail['order_no']], $upData)){
                $this->ajaxReturn(400, '操作失败');
            }
            //记录log
            $orderDetail['status'] = 7;
            $orderDetail['remark'] = OrderLogModel::$remarkArr[7]. '卖家撤销订单';
            $orderDetail['author'] = 'u_'.$this->user_info['user_id'];
            $this->addOrderLog($orderDetail);
            $this->ajaxReturn(0, 'success');
        }
        //发布方撤单
        if($params['operate_type'] == 8){
            if($orderDetail['issue_user_id'] != $this->user_info['user_id']){
                $this->ajaxReturn(400, '非法操作');
            }
            if($orderDetail['status'] != 1){
                $this->ajaxReturn(400, '订单不可撤销状态,请查看订单详情');
            }
            if(!$orderModel->update(['order_no'=> $orderDetail['order_no']], ['status'=> 8, 's_eight_time'=> time()])){
                $this->ajaxReturn(400, '撤单失败');
            }
            //记录log
            $orderDetail['status'] = 8;
            $orderDetail['remark'] = OrderLogModel::$remarkArr[8]. '发布方撤单';
            $orderDetail['author'] = 'u_'.$this->user_info['user_id'];
            $this->addOrderLog($orderDetail);
            $this->ajaxReturn(0, 'success');
        }

        $this->ajaxReturn(400, '错误的操作类型');
    }

    //记录log
    public function addOrderLog($data){
        $orderLogModel = OrderLogModel::getSingleton();
        return $orderLogModel->add([
            'order_no'  => $data['order_no'],
            'b_type'    => $data['b_type'],
            'issue_user_id'     => $data['issue_user_id'],
            'buyer_user_id'     => $data['buyer_user_id'],
            'seller_user_id'    => $data['seller_user_id'],
            'num'               => $data['num'],
            'unit_price'        => $data['unit_price'],
            'total_price'       => $data['total_price'],
            'commission_sacle'  => $data['commission_sacle'],
            'commission_num'    => $data['commission_num'],
            'pay_type'          => $data['pay_type'],
            'status'            => $data['status'],
            'remark'            => $data['remark'],
            'author'            => $data['author']
        ]);
    }
}
